﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using Polenter.Serialization;
using SoTools.Communicator.Messages;
#if WINDOWS_PHONE
using Microsoft.Phone.Reactive;
#else
using System.Reactive.Linq;
#endif

namespace SoTools.Communicator
{
	public sealed partial class Communicator
	{
		private readonly IPAddress _multicastAddress;
		private readonly int _multicastPort;

		private IDisposable _networkObserver;
		private Func<IObservable<byte[]>> _networkObserverFactory;

		public Communicator()
			: this(new byte[] { 224, 1, 2, 3 }, 1234)
		{
		}

		public Communicator(byte[] multicastAddress, int multicastPort)
		{
			if (multicastAddress.Length != 4)
				throw new ArgumentException("Multicast Adress must be 4 bytes", "multicastAddress");

			_multicastAddress = new IPAddress(multicastAddress);
			_multicastPort = multicastPort;
		}

		private event EventHandler<BaseMessageEventArgs> OnMessageReceived;

		private void OnReceive(byte[] received)
		{
			if (_networkObserver != null)
				_networkObserver.Dispose();

			_networkObserver = _networkObserverFactory.Invoke().Subscribe(OnReceive);

			if (received == null)
				return;

			try
			{
				using (var ms = new MemoryStream())
				{
					ms.Write(received, 0, received.Length);
					ms.Flush();
					ms.Position = 0;

					var serializer = new SharpSerializer(true);
					var obj = (BaseMessage)serializer.Deserialize(ms);

					if (OnMessageReceived != null)
						OnMessageReceived(this, new BaseMessageEventArgs { Message = obj });
				}
			}
			catch (Exception exception)
			{
				if (Debugger.IsAttached)
				{
					Debug.WriteLine(exception.Message);
					Debugger.Break();
				}
			}
		}

		private class BaseMessageEventArgs : EventArgs
		{
			public BaseMessage Message { get; set; }
		}
	}
}
